home *** CD-ROM | disk | FTP | other *** search
- FPU emulation code v0.6
-
-
- This is what you need to get Linux to work if you are not
- fortunate enough to own an 68881/2. The file
-
- /usr/src/linux/arch/m68k/kerlenl/traps.c
-
- needs to be adjusted like I did in the included traps.c file.
- You will also need to adjust your bootstrap program to make the
- 68881 the default processor if no FPU is found.
- Also you will have to link math_emu.o to your kernel (of course ;-)
-
- This program is based on the NetBSD FPU emulator.
- The original README is included below. Some changes made by me are:
-
- -Added FSAVE/FRESTORE support (essential for Linux)
- -patches for supervisor mode; new trap handler
- -Linux compatible signal handling
- -bugfixes
- -added the following instructions:
- FSIN,FCOS,FSINCOS,FTAN (more to follow)
-
-
- Paul Coene
-
-
-
- -----------------------------------------------------------------------
- 1. LIST OF IMPLEMENTED AND UNIMPLEMENTED INSTRUCTIONS
-
- This is the list of implemented and unimplemented FPU instructions.
- All 040's FP instructions except FSAVE and FRESTORE are implemented.
-
- Type field = bit 8-6 of opcode word
-
- 1-1. Implemented Instructions
-
- Type=0: FMOVE (mem->FPr), FINT, FINTRZ, FSQRT, FABS, FNEG, FGETEXP,
- FGETMAN, FDIV, FADD, FMUL, FSGLDIV, FSCALE, FSGLMUL, FSUB,
- FCMP, FTST, FMOVE (FPr->mem), FMOVEM (FPr), FMOVEM (FPcr),
- FMOVECR, FLOGNP1, FLOGN, FLOG10, FLOG2, FMOD, FREM
-
- Type=1: FDBcc, FScc, FTRAPcc,
-
- Type=2: FBcc (word, incl. FNOP)
-
- Type=3: FBcc (long)
-
- Type=4: none
-
- Type=5: none
-
- 1-2. Unimplemented Instructions
-
- Type=0: FSINH, FETOXM1, FTANH, FATAN, FASIN, FATANH, FSIN, FTAN,
- FETOX, FTWOTOX, FTENTOX, FCOSH, FACOS, FCOS, FSINCOS
-
- Type=1: none
-
- Type=2: none
-
- Type=3: none
-
- Type=4: FSAVE
-
- Type=5: FRESTORE
-
-
- 2. WHAT ARE MISSING BESIDES UNIMPLEMENTED INSTRUCTIONS
-
- Missing is Packed BCD support, but I do not feel any particular need
- for it. But if anyone wants it, feel free to add the PBCD support;
- all we need is type conversion from PBCD external type to internal FP
- number format and vice versa. No FP arithmetic is done in external
- formats (i.e. byte/word/long integers, single/double/extended IEEE FPs
- or PBCD); they are first converted into the internal format then used
- for calculations.
-
-
- 3. HOW TO ADD A NEW INSTRUCTION SUPPORT
-
- Since we need not support FSAVE and FRESTORE operations, all
- instructions we have to implement are type 0, all of which are
- arithmetic operations. It is particularly easy to add a new
- arithmetic instruction to the existing ones (not to say it is easy to
- write a "stable" function to perform floating point
- operations... that's entirely another matter). In "fpu_emulate.c",
- there's a function fpu_emul_arith(). In it, there's a large switch()
- { case ... } which dispatch each instruction emulator function. An
- emulator function of any type 0 arithmetic instruction follows this
- prototype:
-
- struct fpn *fpu_op(struct fpemu *fe);
-
- Where fe is a pointer to a struct where frame, fpframe, and fetched
- operands are accessible. That's right, you don't have to fetch the
- operands by yourself in you emulation funtion. For instance, the parts
- calling FSQRT, FSUB, FADD and FTST look like:
-
- switch(word1 & 0x3F) {
- [...]
- case 0x04: /* fsqrt */
- res = fpu_sqrt(fe);
- break;
- [...]
- case 0x28: /* fsub */
- fe->fe_f2.fp_sign = !fe->fe_f2.fp_sign; /* f2 = -f2 */
- case 0x22: /* fadd */
- res = fpu_add(fe);
- break;
- [...]
- case 0x3A: /* ftst */
- res = &fe->fe_f2;
- no_store = 1;
- break;
- [...]
- default:
- sig = SIGILL;
- } /* switch */
-
- Here, fe->fe_f1 and fe->fe_f2 are fetched operands. You can use
- fe->fe_f3 for storing the result, or you can return a pointer to
- either operand if you want to. At any rate, you have to follow
- the following rules:
-
- 1) A diadic instruction takes two operands fe->fe_f1 & fe->fe_f2.
- 2) A monadic instruction takes one operands fe->fe_f2 (NOT fe_f1).
- 3) Must return a pointer to struct fpn where the result is stored.
- 4) If exceptions are detected, set corresponding bits in fe->fe_fpsr.
- The rest is taken care of in fpu_emul_arith().
- 5) Condition code need not be calculated. It's taken care of in
- fpu_emul_arith().
-
- Actually, after above was written, stubs for the missing functions are
- added to the source, so you do not have to change fpu_emul_arith() at
- all. Function names and prototypes are in fpu_arith_proto.h, and all
- (except fpu_sincos()) follows the rules above.
-
-
- 4. OTHER POSSIBLE IMPROVEMENTS
-
- 4-1. THINGS NOT MENTIONED HERE
-
- I'm sure we could use any kind of improvements from anyone. The
- following thing(s) is(are) what I can think of off hand.
-
- 4-2. SPEED
-
- Probably the precision (115-bit significand) derived from Sparc FPE is
- not necessary and slowing things down. Reducing precision to
- something which would make more sense in the context of m68k, like
- 67-bits (64 + guard/round/sticky bits), would not be trivial since
- reference to 4 significand words is scattered all over the code
- whether Sparc-derived or not. But it would be a good project.
-
- Also, addition/subtraction of significand (= long integer) could be
- done in assembly instead of C as is currently done. This might speed
- things up a little bit.
-
-